<?php
/*
 * description：
 * author：wh
 * email：
 * createTime：{2024/7/27} {17:36} 
 */

namespace wanghua\general_utility_tools_php\algorithm;


/**
 * 常见算法
 * Class AlgorithmTools
 * @package wanghua\general_utility_tools_php\tool
 */
class Algorithm
{

    /**
     * desc：权重随机选择算法
     *
     * 使用场景：转盘抽奖等需要指定概率的场景
     *
     * author：wh
     * @param array $weights 权重数组 eg：[1, 9, 30, 70] 概率的总和是100%
     * return 返回计算后的索引
     */
    static function weightRandom($weights){
        //$weights = [1, 9, 30, 70]; // 权重数组
        $totalWeight = array_sum($weights);
        $min_num = min($weights);//取出数组中最小的值
        $random = mt_rand($min_num, $totalWeight); // 生成一个最小元素到总权重的随机数

        $cumulativeWeight = 0; // 累积权重
        $selected = 0; // 选择的索引

        foreach ($weights as $index => $weight) {
            $cumulativeWeight += $weight; // 累加权重
            if ($random <= $cumulativeWeight) {
                $selected = $index; // 根据权重选择索引
                break;
            }
        }
        //输出选择的索引
        return $selected;
    }

    /**
     * desc：测试权重随机算法概率
     * author：wh
     * @param array $weights 权重数组 eg：[1, 9, 30, 70]
     */
    static function testWeightRandom(array $weights){
        echo json_encode($weights)."\n";

        $trials = 1000; // 试验次数
        $selectionCounts = array_fill(0, count($weights), 0); // 用于存储每个索引的选择次数

        for ($i = 0; $i < $trials; $i++) {

            $index = self::weightRandom($weights);
            $selectionCounts[$index]++; // 记录选择次数
        }

        // 计算每个索引的选择概率
        $probabilities = [];
        foreach ($selectionCounts as $index => $count) {
            $probabilities[$index] = ($count / $trials) * 100; // 转换为百分比
        }

        // 输出结果
        echo "After {$trials} trials, the probabilities of selecting each index are:\n";
        foreach ($probabilities as $index => $probability) {
            echo "Index {$index}: {$probability}%\n";
        }
    }

    /**
     * desc：洗牌算法
     *
     * 对数组进行随机排序，实现洗牌算法
     * author：wh
     * @param array $items eg: [1, 2, 3, 4, 5]
     * @return array 返回计算后的数组
     */
    static function shuffle(array $items) {
        //$items = [1, 2, 3, 4, 5];
        shuffle($items);
        return $items;
    }

    /**
     * 随机密码生成算法
     *
     * 作用：创建安全的随机密码，常用于用户注册或密码重置
     * 使用场景：用户账户创建、密码重置链接生成
     */
    static function randomPassword($length = 8) {
        $password = '';
        $possibleChars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

        for ($i = 0; $i < $length; $i++) {
            $password .= substr($possibleChars, mt_rand(0, strlen($possibleChars) - 1), 1);
        }
        return $password;
    }

    /**
     * 随机颜色生成算法
     *
     * 作用：生成随机RGB颜色值，可用于网页设计中动态改变元素颜色
     * 使用场景：动态网页背景、随机颜色显示的元素
     */
    static function randomColor() {
        $red = mt_rand(0, 255);
        $green = mt_rand(0, 255);
        $blue = mt_rand(0, 255);
        return [$red, $green, $blue];
    }
}